1
|
|
|
/** |
2
|
|
|
* eGroupWare API: JSON - Contains the client side javascript implementation of class.egw_json.inc.php |
3
|
|
|
* |
4
|
|
|
* @link http://www.egroupware.org |
5
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License |
6
|
|
|
* @package api |
7
|
|
|
* @subpackage ajax |
8
|
|
|
* @author Andreas Stoeckel <[email protected]> |
9
|
|
|
* @version $Id$ |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
/*egw:uses |
13
|
|
|
jsapi.jsapi; // Contains some helper functions |
14
|
|
|
vendor.bower-asset.jquery.dist.jquery; // Used for the ajax requests |
15
|
|
|
*/ |
16
|
|
|
|
17
|
|
|
/* The egw_json_request is the javaScript side implementation of class.egw_json.inc.php.*/ |
18
|
|
|
|
19
|
|
View Code Duplication |
function _egw_json_escape_string(input) |
20
|
|
|
{ |
21
|
|
|
var len = input.length; |
22
|
|
|
var res = ""; |
23
|
|
|
|
24
|
|
|
for (var i = 0; i < len; i++) |
25
|
|
|
{ |
26
|
|
|
switch (input.charAt(i)) |
27
|
|
|
{ |
28
|
|
|
case '"': |
29
|
|
|
res += '\\"'; |
30
|
|
|
break; |
31
|
|
|
|
32
|
|
|
case '\n': |
33
|
|
|
res += '\\n'; |
34
|
|
|
break; |
35
|
|
|
|
36
|
|
|
case '\r': |
37
|
|
|
res += '\\r'; |
38
|
|
|
break; |
39
|
|
|
|
40
|
|
|
case '\\': |
41
|
|
|
res += '\\\\'; |
42
|
|
|
break; |
43
|
|
|
|
44
|
|
|
case '\/': |
45
|
|
|
res += '\\/'; |
46
|
|
|
break; |
47
|
|
|
|
48
|
|
|
case '\b': |
49
|
|
|
res += '\\b'; |
50
|
|
|
break; |
51
|
|
|
|
52
|
|
|
case '\f': |
53
|
|
|
res += '\\f'; |
54
|
|
|
break; |
55
|
|
|
|
56
|
|
|
case '\t': |
57
|
|
|
res += '\\t'; |
58
|
|
|
break; |
59
|
|
|
|
60
|
|
|
default: |
61
|
|
|
res += input.charAt(i); |
62
|
|
|
} |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
return res; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
function _egw_json_encode_simple(input) |
69
|
|
|
{ |
70
|
|
|
switch (input.constructor) |
71
|
|
|
{ |
72
|
|
|
case String: |
73
|
|
|
return '"' + _egw_json_escape_string(input) + '"'; |
74
|
|
|
|
75
|
|
|
case Number: |
76
|
|
|
return input.toString(); |
77
|
|
|
|
78
|
|
|
case Boolean: |
79
|
|
|
return input ? 'true' : 'false'; |
80
|
|
|
|
81
|
|
|
default: |
82
|
|
|
return null; |
83
|
|
|
} |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
function egw_json_encode(input) |
87
|
|
|
{ |
88
|
|
|
egw.debug("warn", "Function %s is deprecated, use egw.jsonEncode() instead", arguments.callee.name); |
89
|
|
|
return egw.jsonEncode(input); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Some variables needed to store which JS and CSS files have already be included |
95
|
|
|
*/ |
96
|
|
|
var egw_json_files = {}; |
97
|
|
|
|
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Initialize the egw_json_files object with all files which are already bound in |
101
|
|
|
*/ |
102
|
|
|
jQuery(document).ready(function() { |
103
|
|
|
jQuery("script, link").each(function() { |
104
|
|
|
var file = false; |
105
|
|
|
if (jQuery(this).attr("src")) { |
106
|
|
|
file = jQuery(this).attr("src"); |
107
|
|
|
} else if (jQuery(this).attr("href")) { |
108
|
|
|
file = jQuery(this).attr("href"); |
109
|
|
|
} |
110
|
|
|
if (file) { |
111
|
|
|
egw_json_files[file] = true; |
112
|
|
|
} |
113
|
|
|
}); |
114
|
|
|
}); |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Variable which stores all currently registered plugins |
118
|
|
|
*/ |
119
|
|
|
var _egw_json_plugins = []; |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* Register a plugin for the egw_json handler |
123
|
|
|
*/ |
124
|
|
|
function egw_json_register_plugin(_callback, _context) |
125
|
|
|
{ |
126
|
|
|
egw.debug("warn", "Function %s is deprecated", arguments.callee.name); |
127
|
|
|
//Default the context parameter to "window" |
128
|
|
|
if (typeof _context == 'undefined') { |
129
|
|
|
_context = window; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
//Add a plugin object to the plugins array |
133
|
|
|
_egw_json_plugins[_egw_json_plugins.length] = { |
134
|
|
|
'callback': _callback, |
135
|
|
|
'context': _context |
136
|
|
|
}; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Function used internally to pass a response to all registered plugins |
141
|
|
|
*/ |
142
|
|
|
function _egw_json_plugin_handle(_type, _response, _context) { |
143
|
|
|
for (var i = 0; i < _egw_json_plugins.length; i++) |
144
|
|
|
{ |
145
|
|
|
try { |
146
|
|
|
var plugin = _egw_json_plugins[i]; |
147
|
|
|
|
148
|
|
|
var context = plugin.context; |
149
|
|
|
if (!plugin.context && typeof _context != "undefined") |
150
|
|
|
{ |
151
|
|
|
context = _context; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
if (plugin.callback.call(context, _type, _response)) { |
155
|
|
|
return true; |
156
|
|
|
} |
157
|
|
|
} catch (e) { |
158
|
|
|
if (typeof console != 'undefined') |
159
|
|
|
{ |
160
|
|
|
console.log(e); |
|
|
|
|
161
|
|
|
} |
162
|
|
|
} |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
return false; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** The constructor of the egw_json_request class. |
169
|
|
|
* |
170
|
|
|
* @param string _menuaction the menuaction function which should be called and |
171
|
|
|
* which handles the actual request. If the menuaction is a full featured |
172
|
|
|
* url, this one will be used instead. |
173
|
|
|
* @param array _parameters which should be passed to the menuaction function. |
174
|
|
|
* @param object _context is the context which will be used for the callbacks (not callback of sendRequest!) |
175
|
|
|
*/ |
176
|
|
|
function egw_json_request(_menuaction, _parameters, _context) |
177
|
|
|
{ |
178
|
|
|
egw.debug("warn", "Function %s is deprecated", arguments.callee.name); |
179
|
|
|
this.context = window.document; |
180
|
|
|
if (typeof _context != 'undefined') |
181
|
|
|
this.context = _context; |
182
|
|
|
|
183
|
|
|
if (typeof _parameters != 'undefined') |
184
|
|
|
{ |
185
|
|
|
this.parameters = _parameters; |
186
|
|
|
} |
187
|
|
|
else |
188
|
|
|
{ |
189
|
|
|
this.parameters = new Array; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
// Check whether the supplied menuaction parameter is a full featured url |
193
|
|
|
// or just a menuaction |
194
|
|
|
if (_menuaction.match(/json.php\?menuaction=[a-z_0-9]*\.[a-z_0-9]*\.[a-z_0-9]*/i)) |
195
|
|
|
{ |
196
|
|
|
// Menuaction is a full featured url |
197
|
|
|
this.url = _menuaction; |
198
|
|
|
} |
199
|
|
|
else |
200
|
|
|
{ |
201
|
|
|
// We only got a menu action, assemble the url manually. |
202
|
|
|
this.url = this._assembleAjaxUrl(_menuaction); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
this.request = null; |
206
|
|
|
this.sender = null; |
207
|
|
|
this.callback = null; |
208
|
|
|
this.alertHandler = this.alertFunc; |
209
|
|
|
this.onLoadFinish = null; |
210
|
|
|
this.loadedJSFiles = {}; |
211
|
|
|
this.handleResponseDone = false; |
212
|
|
|
this.app = null; |
213
|
|
|
if (window.egw_alertHandler) |
214
|
|
|
{ |
215
|
|
|
this.alertHandler = window.egw_alertHandler; |
216
|
|
|
} |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
/** |
220
|
|
|
* Sets the "application" object which is passed to egw_appWindowOpen when a redirect is done |
221
|
|
|
*/ |
222
|
|
|
egw_json_request.prototype.setAppObject = function(_app) |
223
|
|
|
{ |
224
|
|
|
this.app = _app; |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
egw_json_request.prototype._assembleAjaxUrl = function(_menuaction) |
228
|
|
|
{ |
229
|
|
|
// Retrieve the webserver url |
230
|
|
|
var webserver_url = window.egw_webserverUrl || egw_topWindow().egw_webserverUrl; |
231
|
|
|
|
232
|
|
|
// Check whether the webserver_url is really set |
233
|
|
|
// Don't check for !webserver_url as it might be empty. |
234
|
|
|
// Thank you to Ingo Ratsdorf for reporting this. |
235
|
|
|
if (typeof webserver_url == "undefined") |
236
|
|
|
{ |
237
|
|
|
throw "Internal JS error, top window not found, webserver url could not be retrieved."; |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
// Add the ajax relevant parts |
241
|
|
|
return webserver_url + '/json.php?menuaction=' + _menuaction; |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* Sends the AJAX JSON request. |
246
|
|
|
* |
247
|
|
|
* @param boolean _async specifies whether the request should be handeled asynchronously (true, the sendRequest function immediately returns to the caller) or asynchronously (false, the sendRequest function waits until the request is received) |
248
|
|
|
* @param _callback is an additional callback function which should be called upon a "data" response is received |
249
|
|
|
* @param _sender context (this) of _callback (different from _context param of constructor used for standard callbacks!) |
250
|
|
|
*/ |
251
|
|
|
egw_json_request.prototype.sendRequest = function(_async, _callback, _sender) |
252
|
|
|
{ |
253
|
|
|
egw.debug("warn", "egw_json_request is deprecated\n\ |
254
|
|
|
Use egw.json(menuaction, parameters [,callback, context, async, sender]).sendRequest() instead."); |
255
|
|
|
//Store the sender and callback parameter inside this class |
256
|
|
|
this.sender = _sender; |
257
|
|
|
if (typeof _callback != "undefined") |
258
|
|
|
this.callback = _callback; |
259
|
|
|
|
260
|
|
|
//Copy the async parameter which defaults to "true" |
261
|
|
|
var is_async = true; |
262
|
|
|
if (typeof _async != "undefined") |
263
|
|
|
is_async = _async; |
264
|
|
|
|
265
|
|
|
//Assemble the actual request object containing the json data string |
266
|
|
|
var request_obj = { |
267
|
|
|
"json_data": egw.jsonEncode( |
268
|
|
|
{ |
269
|
|
|
"request": { |
270
|
|
|
"parameters": this.parameters |
271
|
|
|
} |
272
|
|
|
}) |
273
|
|
|
}; |
274
|
|
|
|
275
|
|
|
//Send the request via the jquery AJAX interface to the server |
276
|
|
|
this.request = jQuery.ajax({url: this.url, |
277
|
|
|
async: is_async, |
278
|
|
|
context: this, |
279
|
|
|
data: request_obj, |
280
|
|
|
dataType: 'json', |
281
|
|
|
type: 'POST', |
282
|
|
|
success: this.handleResponse, |
283
|
|
|
error: function(_xmlhttp,_err) { |
284
|
|
|
window.console.error('Ajax request to ' + this.url + ' failed: ' + _err); |
285
|
|
|
} |
286
|
|
|
}); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
egw_json_request.prototype.abort = function() |
290
|
|
|
{ |
291
|
|
|
this.request.abort(); |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
egw_json_request.prototype.alertFunc = function(_message, _details) |
295
|
|
|
{ |
296
|
|
|
alert(_message); |
|
|
|
|
297
|
|
|
if(_details) _egw_json_debug_log(_message, _details); |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
function _egw_json_debug_log(_msg, _e) |
301
|
|
|
{ |
302
|
|
|
if (typeof console != "undefined" && typeof console.log != "undefined") |
303
|
|
|
{ |
304
|
|
|
console.log(_msg, _e); |
|
|
|
|
305
|
|
|
} |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
/* Displays an json error message */ |
309
|
|
|
egw_json_request.prototype.jsonError = function(_msg, _e) |
310
|
|
|
{ |
311
|
|
|
var msg = 'EGW JSON Error: '+_msg; |
312
|
|
|
|
313
|
|
|
//Log and show the error message |
314
|
|
|
_egw_json_debug_log(msg, _e); |
315
|
|
|
this.alertHandler(msg); |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
/* Internal function which handles the response from the server */ |
319
|
|
|
egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRequest) |
320
|
|
|
{ |
321
|
|
|
this.handleResponseDone = false; |
322
|
|
|
if (data && data.response) |
323
|
|
|
{ |
324
|
|
|
var hasResponse = false; |
325
|
|
|
// Try to load files using API |
326
|
|
|
if(egw && egw().includeJS) |
327
|
|
|
{ |
328
|
|
|
var js_files = []; |
329
|
|
|
var css_files = []; |
330
|
|
|
for (var i = data.response.length - 1; i > 0; --i) |
331
|
|
|
{ |
332
|
|
|
var res = data.response[i]; |
333
|
|
|
if(res.type == 'js' && typeof res.data == 'string') |
334
|
|
|
{ |
335
|
|
|
js_files.unshift(res.data); |
336
|
|
|
this.loadedJSFiles[res.data] = false; |
337
|
|
|
data.response.splice(i,1); |
338
|
|
|
} |
339
|
|
|
} |
340
|
|
|
if(js_files.length > 0) |
341
|
|
|
{ |
342
|
|
|
egw().includeJS(js_files, function() { |
343
|
|
|
for(var i = 0; i < js_files.length; i++) |
344
|
|
|
{ |
345
|
|
|
this.loadedJSFiles[js_files[i]] = true; |
346
|
|
|
} |
347
|
|
|
this.checkLoadFinish(); |
348
|
|
|
},this); |
349
|
|
|
} |
350
|
|
|
} |
351
|
|
|
for (var i = 0; i < data.response.length; i++) |
352
|
|
|
{ |
353
|
|
|
try |
354
|
|
|
{ |
355
|
|
|
var res = data.response[i]; |
356
|
|
|
|
357
|
|
|
switch (data.response[i].type) |
358
|
|
|
{ |
359
|
|
|
case 'alert': |
360
|
|
|
//Check whether all needed parameters have been passed and call the alertHandler function |
361
|
|
|
if ((typeof res.data.message != 'undefined') && |
362
|
|
|
(typeof res.data.details != 'undefined')) |
363
|
|
|
{ |
364
|
|
|
this.alertHandler( |
365
|
|
|
res.data.message, |
366
|
|
|
res.data.details) |
367
|
|
|
hasResponse = true; |
368
|
|
|
} else |
369
|
|
|
throw 'Invalid parameters'; |
370
|
|
|
break; |
371
|
|
|
case 'assign': |
372
|
|
|
//Check whether all needed parameters have been passed and call the alertHandler function |
373
|
|
|
if ((typeof res.data.id != 'undefined') && |
374
|
|
|
(typeof res.data.key != 'undefined') && |
375
|
|
|
(typeof res.data.value != 'undefined')) |
376
|
|
|
{ |
377
|
|
|
var obj = document.getElementById(res.data.id); |
378
|
|
|
if (obj) |
379
|
|
|
{ |
380
|
|
|
obj[res.data.key] = res.data.value; |
381
|
|
|
|
382
|
|
|
if (res.data.key == "innerHTML") |
383
|
|
|
{ |
384
|
|
|
egw_insertJS(res.data.value); |
385
|
|
|
} |
386
|
|
|
|
387
|
|
|
hasResponse = true; |
388
|
|
|
} |
389
|
|
|
} else |
390
|
|
|
throw 'Invalid parameters'; |
391
|
|
|
break; |
392
|
|
|
case 'data': |
393
|
|
|
//Callback the caller in order to allow him to handle the data |
394
|
|
|
if (this.callback) |
395
|
|
|
{ |
396
|
|
|
this.callback.call(this.sender, res.data); |
397
|
|
|
hasResponse = true; |
398
|
|
|
} |
399
|
|
|
break; |
400
|
|
|
case 'script': |
401
|
|
|
if (typeof res.data == 'string') |
402
|
|
|
{ |
403
|
|
|
try |
404
|
|
|
{ |
405
|
|
|
var func = new Function(res.data); |
|
|
|
|
406
|
|
|
func.call(window); |
407
|
|
|
} |
408
|
|
|
catch (e) |
409
|
|
|
{ |
410
|
|
|
e.code = res.data; |
411
|
|
|
_egw_json_debug_log(e); |
412
|
|
|
} |
413
|
|
|
hasResponse = true; |
414
|
|
|
} else |
415
|
|
|
throw 'Invalid parameters'; |
416
|
|
|
break; |
417
|
|
|
case 'apply': |
418
|
|
|
if (typeof res.data.func == 'string' && typeof window[res.data.func] == 'function') |
419
|
|
|
{ |
420
|
|
|
try |
421
|
|
|
{ |
422
|
|
|
window[res.data.func].apply(window, res.data.parms); |
423
|
|
|
} |
424
|
|
|
catch (e) |
425
|
|
|
{ |
426
|
|
|
_egw_json_debug_log(e, {'Function': res.data.func, 'Parameters': res.data.parms}); |
427
|
|
|
} |
428
|
|
|
hasResponse = true; |
429
|
|
|
} else if (typeof res.data.func == "string" && |
430
|
|
|
res.data.func.substr(0,4) == "app." && app) |
431
|
|
|
{ |
432
|
|
|
|
433
|
|
|
var parts = res.data.func.split("."); |
434
|
|
|
// check if we need a not yet instanciated app.js object --> instanciate it now |
435
|
|
|
if (parts.length == 3 && typeof app[parts[1]] == 'undefined' && |
436
|
|
|
typeof app.classes[parts[1]] == 'function') |
437
|
|
|
{ |
438
|
|
|
app[parts[1]] = new app.classes[parts[1]](); |
439
|
|
|
} |
440
|
|
|
if(parts.length == 3 && typeof app[parts[1]] == "object" && |
441
|
|
|
typeof app[parts[1]][parts[2]] == "function") |
442
|
|
|
{ |
443
|
|
|
try |
444
|
|
|
{ |
445
|
|
|
this.context = app[parts[1]][parts[2]].apply(app[parts[1]], res.data.parms); |
446
|
|
|
} |
447
|
|
|
catch (e) |
448
|
|
|
{ |
449
|
|
|
_egw_json_debug_log(e, {'Function': res.data.func, 'Parameters': res.data.parms}); |
450
|
|
|
} |
451
|
|
|
} |
452
|
|
|
hasResponse = true; |
453
|
|
|
|
454
|
|
|
} else |
455
|
|
|
throw 'Invalid parameters'; |
456
|
|
|
break; |
457
|
|
|
case 'jquery': |
458
|
|
|
if (typeof res.data.select == 'string' && |
459
|
|
|
typeof res.data.func == 'string') |
460
|
|
|
{ |
461
|
|
|
try |
462
|
|
|
{ |
463
|
|
|
var jQueryObject = jQuery(res.data.select, this.context); |
464
|
|
|
jQueryObject[res.data.func].apply(jQueryObject, res.data.parms); |
465
|
|
|
} |
466
|
|
|
catch (e) |
467
|
|
|
{ |
468
|
|
|
_egw_json_debug_log(e, {'Function': res.data.func, 'Parameters': res.data.parms}); |
469
|
|
|
} |
470
|
|
|
hasResponse = true; |
471
|
|
|
} else |
472
|
|
|
throw 'Invalid parameters'; |
473
|
|
|
break; |
474
|
|
|
case 'redirect': |
475
|
|
|
//console.log(res.data.url); |
476
|
|
|
if (typeof res.data.url == 'string' && |
477
|
|
|
typeof res.data.global == 'boolean' && |
478
|
|
|
typeof res.data.app == 'string') |
479
|
|
|
{ |
480
|
|
|
//Special handling for framework reload |
481
|
|
|
res.data.global |= (res.data.url.indexOf("?cd=10") > 0); |
482
|
|
|
|
483
|
|
|
if (res.data.global) |
484
|
|
|
{ |
485
|
|
|
egw_topWindow().location.href = res.data.url; |
486
|
|
|
} |
487
|
|
|
else |
488
|
|
|
{ |
489
|
|
|
egw_appWindowOpen(res.data.app, res.data.url); |
490
|
|
|
} |
491
|
|
|
|
492
|
|
|
hasResponse = true; |
493
|
|
|
} else |
494
|
|
|
throw 'Invalid parameters'; |
495
|
|
|
break; |
496
|
|
|
case 'css': |
497
|
|
|
if (typeof res.data == 'string') |
498
|
|
|
{ |
499
|
|
|
//Check whether the requested file had already be included |
500
|
|
|
if (!egw_json_files[res.data]) |
501
|
|
|
{ |
502
|
|
|
egw_json_files[res.data] = true; |
503
|
|
|
|
504
|
|
|
//Get the head node and append a new link node with the stylesheet url to it |
505
|
|
|
var headID = document.getElementsByTagName('head')[0]; |
506
|
|
|
var cssnode = document.createElement('link'); |
507
|
|
|
cssnode.type = "text/css"; |
508
|
|
|
cssnode.rel = "stylesheet"; |
509
|
|
|
cssnode.href = res.data; |
510
|
|
|
headID.appendChild(cssnode); |
511
|
|
|
} |
512
|
|
|
hasResponse = true; |
513
|
|
|
} else |
514
|
|
|
throw 'Invalid parameters'; |
515
|
|
|
break; |
516
|
|
|
case 'js': |
517
|
|
|
if (typeof res.data == 'string') |
518
|
|
|
{ |
519
|
|
|
//Check whether the requested file had already be included |
520
|
|
|
if (!egw_json_files[res.data]) |
521
|
|
|
{ |
522
|
|
|
egw_json_files[res.data] = true; |
523
|
|
|
|
524
|
|
|
//Get the head node and append a new script node with the js file to it |
525
|
|
|
var headID = document.getElementsByTagName('head')[0]; |
526
|
|
|
var scriptnode = document.createElement('script'); |
527
|
|
|
scriptnode.type = "text/javascript"; |
528
|
|
|
scriptnode.src = res.data; |
529
|
|
|
scriptnode._originalSrc = res.data; |
530
|
|
|
headID.appendChild(scriptnode); |
531
|
|
|
|
532
|
|
|
//Increment the includedJSFiles count |
533
|
|
|
this.loadedJSFiles[res.data] = false; |
534
|
|
|
|
535
|
|
|
if (typeof console != 'undefined' && typeof console.log != 'undefined') |
536
|
|
|
console.log("Requested JS file '%s' from server", res.data); |
|
|
|
|
537
|
|
|
|
538
|
|
|
var self = this; |
539
|
|
|
|
540
|
|
|
//FF, Opera, Chrome |
541
|
|
|
scriptnode.onload = function(e) { |
542
|
|
|
var file = e.target._originalSrc; |
543
|
|
|
if (typeof console != 'undefined' && typeof console.log != 'undefined') |
544
|
|
|
console.log("Retrieved JS file '%s' from server", file); |
|
|
|
|
545
|
|
|
|
546
|
|
|
self.loadedJSFiles[file] = true; |
|
|
|
|
547
|
|
|
self.checkLoadFinish(); |
548
|
|
|
}; |
549
|
|
|
|
550
|
|
|
//IE |
551
|
|
|
if (typeof scriptnode.readyState != 'undefined') |
552
|
|
|
{ |
553
|
|
|
if (scriptnode.readyState != 'complete' && |
554
|
|
|
scriptnode.readyState != 'loaded') |
555
|
|
|
{ |
556
|
|
|
scriptnode.onreadystatechange = function() { |
557
|
|
|
var node = window.event.srcElement; |
558
|
|
|
if (node.readyState == 'complete' || node.readyState == 'loaded') { |
559
|
|
|
var file = node._originalSrc; |
560
|
|
|
if (typeof console != 'undefined' && typeof console.log != 'undefined') |
561
|
|
|
console.log("Retrieved JS file '%s' from server", [file]); |
|
|
|
|
562
|
|
|
|
563
|
|
|
self.loadedJSFiles[file] = true; |
|
|
|
|
564
|
|
|
self.checkLoadFinish(); |
565
|
|
|
} |
566
|
|
|
}; |
567
|
|
|
} |
568
|
|
|
else |
569
|
|
|
{ |
570
|
|
|
this.loadedJSFiles[res.data] = true; |
571
|
|
|
} |
572
|
|
|
} |
573
|
|
|
} |
574
|
|
|
hasResponse = true; |
575
|
|
|
} else |
576
|
|
|
throw 'Invalid parameters'; |
577
|
|
|
break; |
578
|
|
|
case 'error': |
579
|
|
|
if (typeof res.data == 'string') |
580
|
|
|
{ |
581
|
|
|
this.jsonError(res.data); |
582
|
|
|
hasResponse = true; |
583
|
|
|
} else |
584
|
|
|
throw 'Invalid parameters'; |
585
|
|
|
break; |
586
|
|
|
} |
587
|
|
|
|
588
|
|
|
//Try to handle the json response with all registered plugins |
589
|
|
|
hasResponse |= _egw_json_plugin_handle(data.response[i].type, res, this.context); |
590
|
|
|
} catch(e) { |
591
|
|
|
this.jsonError('Internal JSON handler error', e); |
592
|
|
|
} |
593
|
|
|
} |
594
|
|
|
|
595
|
|
|
/* If no explicit response has been specified, call the callback (if one was set) */ |
596
|
|
|
if (!hasResponse && this.callback && data.response[i]) |
597
|
|
|
{ |
598
|
|
|
this.callback.call(this.sender, data.response[i].data); |
599
|
|
|
} |
600
|
|
|
|
601
|
|
|
this.handleResponseDone = true; |
602
|
|
|
|
603
|
|
|
this.checkLoadFinish(); |
604
|
|
|
} |
605
|
|
|
} |
606
|
|
|
|
607
|
|
|
/** |
608
|
|
|
* The "onLoadFinish" handler gets called after all JS-files have been loaded |
609
|
|
|
* successfully |
610
|
|
|
*/ |
611
|
|
|
egw_json_request.prototype.checkLoadFinish = function() |
612
|
|
|
{ |
613
|
|
|
var complete = true; |
614
|
|
|
for (var key in this.loadedJSFiles) { |
615
|
|
|
complete = complete && this.loadedJSFiles[key]; |
616
|
|
|
} |
617
|
|
|
|
618
|
|
|
if (complete && this.onLoadFinish && this.handleResponseDone) |
619
|
|
|
{ |
620
|
|
|
this.onLoadFinish.call(this.sender); |
621
|
|
|
} |
622
|
|
|
} |
623
|
|
|
|
624
|
|
|
function egw_json_getFormValues(_form, _filterClass) |
625
|
|
|
{ |
626
|
|
|
egw.debug("warn", "Function %s is deprecated", arguments.callee.name); |
627
|
|
|
var elem = null; |
628
|
|
|
if (typeof _form == 'object') |
629
|
|
|
{ |
630
|
|
|
elem = _form; |
631
|
|
|
} |
632
|
|
|
else |
633
|
|
|
{ |
634
|
|
|
elem = document.getElementsByName(_form)[0]; |
635
|
|
|
} |
636
|
|
|
|
637
|
|
|
var serialized = new Object; |
638
|
|
|
if (typeof elem != "undefined" && elem && elem.childNodes) |
639
|
|
|
{ |
640
|
|
|
if (typeof _filterClass == 'undefined') |
641
|
|
|
_filterClass = null; |
642
|
|
|
|
643
|
|
|
_egw_json_getFormValues(serialized, elem.childNodes, _filterClass) |
644
|
|
|
} |
645
|
|
|
|
646
|
|
|
return serialized; |
647
|
|
|
} |
648
|
|
|
|
649
|
|
|
/** |
650
|
|
|
* Deprecated legacy xajax wrapper functions for the new egw_json interface |
651
|
|
|
*/ |
652
|
|
|
_xajax_doXMLHTTP = function(_async, _menuaction, _arguments) |
653
|
|
|
{ |
654
|
|
|
egw.debug("warn", "Function %s is deprecated", arguments.callee.name); |
655
|
|
|
/* Assemble the parameter array */ |
656
|
|
|
var paramarray = new Array(); |
657
|
|
|
for (var i = 1; i < _arguments.length; i++) |
658
|
|
|
{ |
659
|
|
|
paramarray[paramarray.length] = _arguments[i]; |
660
|
|
|
} |
661
|
|
|
|
662
|
|
|
/* Create a new request, passing the menuaction and the parameter array */ |
663
|
|
|
var request = new egw_json_request(_menuaction, paramarray); |
664
|
|
|
|
665
|
|
|
/* Send the request */ |
666
|
|
|
request.sendRequest(_async); |
667
|
|
|
|
668
|
|
|
return request; |
669
|
|
|
} |
670
|
|
|
|
671
|
|
|
xajax_doXMLHTTP = function(_menuaction) |
672
|
|
|
{ |
673
|
|
|
return _xajax_doXMLHTTP(true, _menuaction, arguments); |
674
|
|
|
} |
675
|
|
|
|
676
|
|
|
xajax_doXMLHTTPsync = function(_menuaction) |
677
|
|
|
{ |
678
|
|
|
return _xajax_doXMLHTTP(false, _menuaction, arguments); |
679
|
|
|
}; |
680
|
|
|
|
681
|
|
|
window.xajax = { |
682
|
|
|
"getFormValues": function(_form) |
683
|
|
|
{ |
684
|
|
|
return egw_json_getFormValues(_form); |
685
|
|
|
} |
686
|
|
|
}; |
687
|
|
|
|
688
|
|
|
/* |
689
|
|
|
The following code is adapted from the xajax project which is licensed under |
690
|
|
|
the following license |
691
|
|
|
@copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson |
692
|
|
|
@copyright Copyright (c) 2008-2009 by Joseph Woolley, Steffen Konerow, Jared White & J. Max Wilson |
693
|
|
|
@license http://www.xajaxproject.org/bsd_license.txt BSD License |
694
|
|
|
*/ |
695
|
|
|
|
696
|
|
|
/** |
697
|
|
|
* used internally by the legacy "egw_json_response.getFormValues" to recursively |
698
|
|
|
* run over all form elements |
699
|
|
|
* @param serialized is the object which will contain the form data |
700
|
|
|
* @param children is the children node of the form we're runing over |
701
|
|
|
* @param string _filterClass if given only return |
702
|
|
|
*/ |
703
|
|
|
function _egw_json_getFormValues(serialized, children, _filterClass) |
704
|
|
|
{ |
705
|
|
|
egw.debug("warn", "Function %s is deprecated", arguments.callee.name); |
706
|
|
|
//alert('_egw_json_getFormValues(,,'+_filterClass+')'); |
707
|
|
|
for (var i = 0; i < children.length; ++i) { |
708
|
|
|
var child = children[i]; |
709
|
|
|
|
710
|
|
|
if (typeof child.childNodes != "undefined") |
711
|
|
|
_egw_json_getFormValues(serialized, child.childNodes, _filterClass); |
712
|
|
|
|
713
|
|
|
if ((!_filterClass || jQuery(child).hasClass(_filterClass)) && typeof child.name != "undefined") |
714
|
|
|
{ |
715
|
|
|
//alert('_egw_json_getFormValues(,,'+_filterClass+') calling _egw_json_getFormValue for name='+child.name+', class='+child.class+', value='+child.value); |
716
|
|
|
_egw_json_getFormValue(serialized, child); |
717
|
|
|
} |
718
|
|
|
} |
719
|
|
|
} |
720
|
|
|
|
721
|
|
|
function _egw_json_getObjectLength(_obj) |
722
|
|
|
{ |
723
|
|
|
var res = 0; |
724
|
|
|
for (key in _obj) |
725
|
|
|
{ |
726
|
|
|
if (_obj.hasOwnProperty(key)) |
727
|
|
|
res++; |
728
|
|
|
} |
729
|
|
|
return res; |
730
|
|
|
} |
731
|
|
|
|
732
|
|
|
/** |
733
|
|
|
* used internally to serialize |
734
|
|
|
*/ |
735
|
|
|
function _egw_json_getFormValue(serialized, child) |
736
|
|
|
{ |
737
|
|
|
//Return if the child doesn't have a name, is disabled, or is a radio-/checkbox and not checked |
738
|
|
|
if ((typeof child.name == "undefined") || (child.disabled && child.disabled == true) || |
739
|
|
|
(child.type && (child.type == 'radio' || child.type == 'checkbox' || child.type == 'button' || child.type == 'submit') && (!child.checked))) |
740
|
|
|
{ |
741
|
|
|
return; |
742
|
|
|
} |
743
|
|
|
|
744
|
|
|
var name = child.name; |
745
|
|
|
var values = null; |
746
|
|
|
|
747
|
|
|
if ('select-multiple' == child.type) |
748
|
|
|
{ |
749
|
|
|
values = new Array; |
750
|
|
|
for (var j = 0; j < child.length; ++j) |
751
|
|
|
{ |
752
|
|
|
var option = child.options[j]; |
753
|
|
|
if (option.selected == true) |
754
|
|
|
values.push(option.value); |
755
|
|
|
} |
756
|
|
|
} |
757
|
|
|
else |
758
|
|
|
{ |
759
|
|
|
values = child.value; |
760
|
|
|
} |
761
|
|
|
|
762
|
|
|
//Special treatment if the name of the child contains a [] - then all theese |
763
|
|
|
//values are added to an array. |
764
|
|
|
var keyBegin = name.indexOf('['); |
765
|
|
|
if (0 <= keyBegin) { |
766
|
|
|
var n = name; |
767
|
|
|
var k = n.substr(0, n.indexOf('[')); |
768
|
|
|
var a = n.substr(n.indexOf('[')); |
769
|
|
|
if (typeof serialized[k] == 'undefined') |
770
|
|
|
serialized[k] = new Object; |
771
|
|
|
|
772
|
|
|
var p = serialized; // pointer reset |
773
|
|
|
while (a.length != 0) { |
774
|
|
|
var sa = a.substr(0, a.indexOf(']')+1); |
775
|
|
|
|
776
|
|
|
var lk = k; //save last key |
777
|
|
|
var lp = p; //save last pointer |
778
|
|
|
|
779
|
|
|
a = a.substr(a.indexOf(']')+1); |
780
|
|
|
p = p[k]; |
781
|
|
|
k = sa.substr(1, sa.length-2); |
782
|
|
|
if (k == '') { |
783
|
|
|
if ('select-multiple' == child.type) { |
784
|
|
|
k = lk; //restore last key |
785
|
|
|
p = lp; |
786
|
|
|
} else { |
787
|
|
|
k = _egw_json_getObjectLength(p); |
788
|
|
|
} |
789
|
|
|
} |
790
|
|
|
if (typeof p[k] == 'undefined') |
791
|
|
|
{ |
792
|
|
|
p[k] = new Object; |
793
|
|
|
} |
794
|
|
|
} |
795
|
|
|
p[k] = values; |
796
|
|
|
} else { |
797
|
|
|
//Add the value to the result object with the given name |
798
|
|
|
if (typeof values != "undefined") |
799
|
|
|
{ |
800
|
|
|
serialized[name] = values; |
801
|
|
|
} |
802
|
|
|
} |
803
|
|
|
} |
804
|
|
|
|